package com.yswy.app.service.impl;


import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayTradePayResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yswy.app.service.*;
import com.yswy.common.enums.PaymentStateEnums;
import com.yswy.common.enums.WxPayMethodEnums;
import com.yswy.common.utils.UserLockUtils;
import com.yswy.common.wxOrder.V3.GenerateSignVo;
import com.yswy.common.wxOrder.V3.WxPayConfigV3;
import com.yswy.common.wxOrder.V3.wxPayV3Callback.WxPayCallbackUtil;
import com.yswy.domain.entity.PayOrderWxLog;
import com.yswy.domain.entity.VipPrice;
import com.yswy.domain.mapper.PayOrderWxLogMapper;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;

@Service
@Slf4j
public class PayOrderWxLogServiceImpl extends ServiceImpl<PayOrderWxLogMapper, PayOrderWxLog> implements PayOrderWxLogService {


    @Autowired
    private PayOrderService payOrderService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private WxPayKeyService wxPayKeyService;
    @Override
    public PayOrderWxLog generateOrder(String orderid ,
                                        GenerateSignVo generateSignVo ,
                                        WxPayConfigV3 wxPayConfigV3,
                                        String uid,
                                        VipPrice vipPrice,
                                        String ip) {


        PayOrderWxLog order = new PayOrderWxLog();
        order.setMchId(wxPayConfigV3.getMchId());
        order.setAppid(wxPayConfigV3.getAppid());
        order.setOrderId(orderid);
        order.setAlitradeno(generateSignVo.getPrepayId());
        order.setTradeStr(JSONObject.fromObject(generateSignVo).toString());
        order.setState(PaymentStateEnums.NEW.getCode());
        order.setUid(uid);
        order.setChannelIp(ip);
        order.setPayType(0);
        order.setRechargeCount(vipPrice.getPrice());
        vipPrice.setUpdateTime(null);
        vipPrice.setCreateTime(null);
        order.setItemInfo(JSONObject.fromObject(vipPrice).toString() );
        order.setCreateTime(new Date());

        save(order);
        return order;
    }

    @Override
    public PayOrderWxLog generateOrder(String orderid, String generateSignVo, WxPayConfigV3 wxPayConfigV3, String uid, VipPrice vipPrice, String ip) {
        PayOrderWxLog order = new PayOrderWxLog();
        order.setMchId(wxPayConfigV3.getMchId());
        order.setAppid(wxPayConfigV3.getAppid());
        order.setOrderId(orderid);
        order.setAlitradeno(null);
        order.setTradeStr(generateSignVo);
        order.setState(PaymentStateEnums.NEW.getCode());
        order.setUid(uid);
        order.setChannelIp(ip);
        order.setPayType(0);
        order.setRechargeCount(vipPrice.getPrice());
        vipPrice.setDescDetails(null);
        vipPrice.setUpdateTime(null);
        vipPrice.setCreateTime(null);
        order.setItemInfo(JSONObject.fromObject(vipPrice).toString() );
        order.setCreateTime(new Date());

        save(order);
        return order;
    }


    @Override
    public String callbackWXPayOrder(HttpServletRequest request, HttpServletResponse response) throws Exception {


        WxPayConfigV3 wxPayConfigV3 = wxPayKeyService.cutAppId(WxPayMethodEnums.APP_PAY_USED.getMessage());

        return WxPayCallbackUtil.wxPaySuccessCallback(request, response, null, wxPayConfigV3, callbackData -> {
            // TODO 处理你的业务逻辑，下面说一下一般业务逻辑处理方法
            log.info("微信支付返回的信息：{}", callbackData);
            String orderId = callbackData.getOrderId();
            String transactionId = callbackData.getTransactionId();
            String tradestate = callbackData.getTradestate();
            Date successTime = callbackData.getSuccessTime();
            BigDecimal  totalMoney = callbackData.getTotalMoney().multiply(new BigDecimal("100"));//元
            PayOrderWxLog payOrderWxLog = getOne(new LambdaQueryWrapper<PayOrderWxLog>().eq(PayOrderWxLog::getOrderId , orderId));
            if (payOrderWxLog == null){
                log.warn("微信支付支付回调-订单号{}交易成功,回调数据服失败", orderId + " 订单未查询到");
                return;
            }

            BigDecimal rechargeCount = new BigDecimal(payOrderWxLog.getRechargeCount()) ;


            /**
             * 交易状态
             * SUCCESS：支付成功
             * REFUND：转入退款
             * NOTPAY：未支付
             * CLOSED：已关闭
             * REVOKED：已撤销（付款码支付）
             * USERPAYING：用户支付中（付款码支付）
             * PAYERROR：支付失败(其他原因，如银行返回失败)
             */
            Boolean isCallbackServcie = false ;
            if ("SUCCESS".equals(tradestate)) {
                log.info("微信支付回调-订单号{}交易成功", orderId);
                if (rechargeCount.compareTo(totalMoney) >=0){
                    payOrderWxLog.setAlitradeno(transactionId);
                    payOrderWxLog.setRefundTime(successTime);
                    payOrderWxLog.setState(PaymentStateEnums.TRADE_SUCCESS.getCode());
                    isCallbackServcie = true;
                }else {
                    payOrderWxLog.setAlitradeno(transactionId);
                    payOrderWxLog.setRefundTime(successTime);
                    payOrderWxLog.setState(PaymentStateEnums.TRADE_MONEY_FAIL.getCode());
                    log.warn("微信支付支付回调-订单号{}交易成功,回调数据服失败", orderId + " 订单金额不匹配");
                }
            }else if ("CLOSED".equals(tradestate)){
                log.info("微信支付回调-订单号{}交易关闭", orderId);
                payOrderWxLog.setAlitradeno(transactionId);
                payOrderWxLog.setRefundTime(successTime);
                payOrderWxLog.setState(PaymentStateEnums.TRADE_CLOSED.getCode());
                isCallbackServcie = true;
            }else if ("PAYERROR".equals(tradestate)){
                log.info("微信支付回调-订单号{}交易失败", orderId);
                payOrderWxLog.setAlitradeno(transactionId);
                payOrderWxLog.setRefundTime(successTime);
                payOrderWxLog.setState(PaymentStateEnums.TRADE_FAIL.getCode());
                isCallbackServcie = true;

            }
            if (isCallbackServcie){
                callbackService(payOrderWxLog);
            }
            updateById(payOrderWxLog);
        });
    }

    @Override
    public void callbackWXYwPayOrder(String orderid) {
        PayOrderWxLog payOrderWxLog = getOne(new LambdaQueryWrapper<PayOrderWxLog>().eq(PayOrderWxLog::getOrderId , orderid));
        if (null == payOrderWxLog) {
            log.warn("微信订单号{}不存在", orderid);
            return;
        }
        callbackService(payOrderWxLog);
    }

    public void callbackService(PayOrderWxLog payOrderWxLog) {
        try {
            synchronized (UserLockUtils.getLock("orderid:"+payOrderWxLog.getOrderId())){
                if (payOrderWxLog.getPayType() == 0){//会员购买
                    payOrderService.callbackPayOrder(1 , null , payOrderWxLog);
                }else {
                    log.warn("微信支付回调-订单号{}订单类型不存在", payOrderWxLog.getOrderId());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("微信支付回调-订单号{}交易关闭,回调数据服失败", payOrderWxLog.getOrderId());
        }
    }



    public int getCentFromYuan(String amountYuanStr) {
        BigDecimal amountYuan = new BigDecimal(amountYuanStr);
        BigDecimal unit = new BigDecimal(100);
        BigDecimal amountCent = amountYuan.multiply(unit);
        return amountCent.intValue();
    }

}
